﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Management;
using System.Collections;
// namespaces necesarios para conexión a bd
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlTypes;

using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;

namespace Persistencia_y_capa_de_negocio
{
    /// <summary>
    /// CADRecursoUsuario. Componente de acceso a la base de datos UsuariosRecursos.
    /// </summary>
    public class CADRecursoUsuario
    {
        /// <summary>
        /// Representa una instancia de la clase.De forma que no he de crear
        /// una nueva cada vez.
        /// </summary>
        private static readonly CADRecursoUsuario instancia = new CADRecursoUsuario();
        /// <summary>
        /// Me permite obtener la variable privada instancia de la clase
        /// De esta forma siempre uso el mismo objeto que representa la clase.
        /// </summary>
        public static CADRecursoUsuario Instancia
        {
            get { return instancia; }
        }
        /// <summary>
        /// Variable para almacenar la cadena de conexión
        /// </summary>
        private string cadCon;
        private SqlDataAdapter da;
        private SqlConnection c;
        private DataSet vdb;

                /// <summary>
        /// Constructor por defecto de la clase CADEdificioUsuario
        /// </summary>
        public CADRecursoUsuario()
        {
            try
            {
                cadCon = ConfigurationManager.ConnectionStrings["conexion"].ConnectionString;

                // Creamos la base de datos virtual.
                vdb = new DataSet();

                // Obtenemos una conexión.
                c = new SqlConnection(cadCon);

                // Almacenamos la base de datos en local.
                da = new SqlDataAdapter("Select * from usuariorecursos", c);
                da.Fill(vdb, "usuariorecursos");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public bool InsertarDatosUsuario(int usuario)
        {
            // Obtenemos la tabla recursos.
            DataTable t = new DataTable();
            t = vdb.Tables["usuariorecursos"];
            ArrayList lista = CADRecurso.Instancia.getRecursos();
            foreach (ENRecurso re in lista)
            {
                try
                {
                    // Comprobamos si ya existe el usuario con recursos
                    DataRow r = t.Select("usuario = \'" + re.Nombre + "\'")[0];
                    // En cuyo caso no haremos nada al ya existir un usuario con recursos.
                    return false;
                }
                catch (Exception)
                {
                    // Significa que el resultado ha sido null. O sea que hay que insertar, no modificar.
                    DataRow r = t.NewRow();

                    // Insertamos los valores del nuevo recurso.
                    r["usuario"] = usuario;
                    r["recurso"] = re.Id;
                    r["cantidad"] = 10000;
                    r["fechaultima"] = DateTime.Now;

                    // Añadimos la nueva fila a la tabla virtual.
                    t.Rows.Add(r);
                    SqlCommandBuilder command = new SqlCommandBuilder(da);

                    // Actualizamos los cambios en la BD real.
                    da.Update(vdb, "usuariosrecursos");
                }
            }
            return true;
        }
        /// <summary>
        /// Función que pasandole un usuario y un recurso nos devuelve un ENRecursoUsuario
        /// </summary>
        /// <param name="usuario"></param>
        /// <param name="recurso"></param>
        public ENRecursoUsuario devolverRecursoUsuario(int usuario, int recurso)
        {
            ENRecursoUsuario enres = new ENRecursoUsuario();
            DataTable t = new DataTable();
            DataRow r = null;

            t = vdb.Tables["usuariorecursos"];

            string select = "usuario = \'" + usuario + "\' and recurso = \'" + recurso + "\'";

            try
            {
                r = t.Select(select)[0];
            }
            catch (Exception)
            {
                return null;
            }
            enres.IDTabla = Convert.ToInt32(r["id"]);
            enres.IDUsuario = Convert.ToInt32(r["usuario"]);
            enres.IDRecurso = Convert.ToInt32(r["recurso"]);
            enres.CantidadRes = (float)Convert.ToDouble(r["cantidad"]);
            enres.Fecha = Convert.ToDateTime(r["fechaultima"]);
            return enres;
        }
        /// <summary>
        /// Función que pasandole un usuario y un recurso nos devuelve un ENRecursoUsuario
        /// </summary>
        /// <param name="usuario"></param>
        /// <param name="recurso"></param>
        public ArrayList devolverRecursosUsuario(int usuario)
        {
            // ArrayList de unidades.
            ArrayList lista = new ArrayList();

            // Obtenemos la tabla unidades.
            DataTable t = new DataTable();
            t = vdb.Tables["usuariorecursos"];

            t.Clear();

            da = new SqlDataAdapter("select * from usuariorecursos", c);

            da.Fill(vdb, "usuariorecursos");    // Ahora tenemos todo el contenido de edificios en local.

            t = vdb.Tables["usuariorecursos"];

            // Extraemos los ENUnidad de cada fila de la base de datos.
            foreach (DataRow r in t.Rows)
            {
                ENRecursoUsuario enres = new ENRecursoUsuario();

                // Insertamos los datos en la nueva actividad.
                enres.IDTabla = Convert.ToInt32(r["id"]);
                enres.IDUsuario = Convert.ToInt32(r["usuario"]);
                enres.IDRecurso = Convert.ToInt32(r["recurso"]);
                enres.CantidadRes = (float)Convert.ToDouble(r["cantidad"]);
                enres.Fecha = Convert.ToDateTime(r["fechaultima"]);

                //un = getUnidad(r["nombre"].ToString().Trim());

                lista.Add(enres);
            }

            // Devolvemos el resultado.
            return lista;
        }

        public bool SumarRecursos(int usuario)
        {
            ENRecursoUsuario recursousuario;
            float restotal;
            bool cambiada = false;
            ArrayList recursos = CADRecurso.Instancia.getRecursos();
            ArrayList creadores = CADEdificio.Instancia.getEdificiosTipo(0);
            //ArrayList edUsuario = CADEdificioUsuario.Instancia.obtenerEdificiosUsuario(usuario);
            CADEdificioUsuario.Instancia.obtenerEdificiosUsuario(usuario);

            ENRecursoUsuario enres = new ENRecursoUsuario();
            DataTable t = new DataTable();
            DataRow r = null;

            t = vdb.Tables["usuariorecursos"];

            foreach (ENRecurso res in recursos)//Recorro la lista de recursos
            {
                string select = "usuario = \'" + usuario + "\' and recurso = \'" + res.Id + "\'";

                try
                {
                    r = t.Select(select)[0];
                    restotal = (float)Convert.ToDouble(r["cantidad"]);

                    foreach (ENEdificio edi in creadores) //Recorro la lista de edificios creadores
                    {
                        foreach (int rescreable in edi.RecursosCreables) //Recorro el arraylist de recursos creables por ese edificio
                        {
                            if (res.Id == rescreable) //Compruebo si ambos son iguales, en caso de serlo tengo que comprobar si ese usuario tiene el edificio en cuestión
                            {
                                //return false;
                                EnEdificioUsuario edus = CADEdificioUsuario.Instancia.obtenerEdificioUsuario(usuario, edi.Id);
                                if (edus.NivelEd != 0)
                                {

                                    cambiada = true;
                                    recursousuario = devolverRecursoUsuario(usuario, rescreable);
                                    int tiempo = (int)(DateTime.Now - Convert.ToDateTime(r["fechaultima"])).TotalSeconds;
                                    //Tiene el edificio en cuestión, miraremos el nivel del edificio para sumarselo a la cantidad base.
                                    restotal += ((edus.NivelEd * res.Ratio)*tiempo/60);
                                }
                            }
                        }
                    }
                    r["cantidad"] = restotal;
                    r["fechaultima"] = DateTime.Now;
                    if (cambiada == true)
                    {
                        SqlCommandBuilder command = new SqlCommandBuilder(da);
                        da.Update(vdb, "usuariorecursos");
                    }
                }
                catch (Exception)
                {
                }

                
            }
            
            return true;
        }

        public void RestaRecursos(int usuario, int recurso, float cantidad)
        {
            ENRecursoUsuario enres = new ENRecursoUsuario();
            DataTable t = new DataTable();
            DataRow r = null;

            t = vdb.Tables["usuariorecursos"];
            string select = "usuario = \'" + usuario + "\' and recurso = \'" + recurso + "\'";

            try
            {
                r = t.Select(select)[0];
                r["cantidad"] = (float)Convert.ToDouble(r["cantidad"]) - cantidad;
                SqlCommandBuilder command = new SqlCommandBuilder(da);
                da.Update(vdb, "usuariorecursos");
            }
            catch (Exception)
            {
            }
        }

        public ArrayList getRecursosUsuario(int usuario)
        {
            ArrayList lista = new ArrayList();

            DataTable t = new DataTable();
            t = vdb.Tables["usuariorecursos"];

            t.Clear();

            try
            {
                da = new SqlDataAdapter("select * from usuariorecursos", c);



                da.Fill(vdb, "usuariorecursos");    // Ahora tenemos todo el contenido de edificios en local.

                t = vdb.Tables["usuariorecursos"];

                foreach (DataRow r in t.Rows)
                {
                    ENRecursoUsuario enres = new ENRecursoUsuario();

                    // Insertamos los datos en el nuevo edificio.
                    enres.IDTabla = Convert.ToInt32(r["id"]);
                    enres.IDUsuario = Convert.ToInt32(r["usuario"]);
                    enres.IDRecurso = Convert.ToInt32(r["recurso"]);
                    enres.CantidadRes = (float)Convert.ToDouble(r["cantidad"]);
                    enres.Fecha = Convert.ToDateTime(r["fechaultima"]);
                    lista.Add(enres);
                }
            }
            catch
            {

            }
            return lista;
        }
    }
}